package com.xone.collaboration.service.impl.strategy;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.xone.collaboration.dao.dataobject.Layer;
import com.xone.collaboration.dao.dataobject.LayerExample;
import com.xone.collaboration.dao.mapper.LayerMapper;
import com.xone.collaboration.service.OpStrategy;
import com.xone.collaboration.service.aonntation.Strategy;
import com.xone.collaboration.service.impl.process.OperationContext;
import com.xone.collaboration.service.vo.ElementVO;
import com.xone.collaboration.service.vo.OperationResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Strategy("UPDATE")
@Component
@Slf4j
public class UpdateOpStrategy implements OpStrategy {

    @Autowired
    private LayerMapper mapper;
    
    @Override
    public OperationResult operate(OperationContext context) {
        try{
            List<String> layerIds = context.getElements().stream().map(elementVO -> elementVO.getLayerId()).collect(Collectors.toList());
            LayerExample example = new LayerExample();
            example.createCriteria().andLayerIdIn(layerIds);
            List<Layer> layers = mapper.selectByExampleWithBLOBs(example);
            layers.forEach(layer -> {
                ElementVO elementVO = context.getElements().stream().filter(e->e.getLayerId().equals(layer.getLayerId())).findFirst().get();
                layer.setElementContent(elementVO.getElementContent());
                layer.setPriority(elementVO.getPriority().shortValue());
                HashMap source = layer.getExtension() != null ? JSON.parseObject(layer.getExtension().toString(),HashMap.class) : null;
                HashMap update = elementVO.getExtension();
                HashMap target = Maps.newHashMap();
                merge(source, update, target);
                layer.setExtension(JSON.toJSONString(target));
                mapper.updateByPrimaryKey(layer);
            });
        }catch (Exception e){
            log.error("update layer error:",e);
            return OperationResult.of(false,e.getMessage());
        }
        return OperationResult.of(true,null);
    }

    private void merge(HashMap source, HashMap update, HashMap target) {
        if(source == null && update !=null){
            target = update;
        }else if(source !=null && update == null){
            target = source;
        }else if(source !=null && update != null){
            target.putAll(source);
            target.putAll(update);
        }
    }
}
